<template>
    <div class="flex_row" style="align-items: start; justify-content: start">
        <div class="flex_col">
            <div class="flex_col card p10 m5 fitem" v-for="(item, index) in firms" :key="index">
                <div class="flex_row_center">
                    <label class="flb">固件版本</label>
                    <label>{{ item.version }}</label>
                </div>
                <div class="flex_row_center mt5">
                    <label class="flb">固件大小</label>
                    <label>{{ formatSize(item.size) }}</label>
                </div>
                <div class="flex_row_center mt5">
                    <label class="flb">更新时间</label>
                    <label>{{ formatDate(item.create_timestamp) }}</label>
                </div>
                <div class="flex_row_center mt5">
                    <label class="flb">固件描述</label>
                    <label>{{ item.description }}</label>
                </div>
                <div class="flex_row_center mt5">
                    <el-button @click="onClickDelete(item.id)" type="warning">删除</el-button>
                    <el-button type="info" @click="onClickUpload(item)">升级</el-button>
                </div>
            </div>
        </div>
        <div class="flex_col p10 ml5">
            <div class="flex_row_center">
                <label class="flb">固件类型</label>
                <el-select class="finput" @change="update" v-model="form.firmType">
                    <el-option v-for="(item, index) in FIRM_TYPS" :key="index" :label="item" :value="index" />
                </el-select>
            </div>
            <div class="flex_row_center mt5">
                <label class="flb">固件版本</label>
                <el-input v-model="form.version" clearable class="finput" />
            </div>
            <div class="flex_row_center mt5">
                <label class="flb">固件描述</label>
                <el-input v-model="form.description" class="finput" :rows="4" type="textarea" />
            </div>
            <div class="flex_row_center mt5">
                <label>选择文件:{{ form.fileName }}</label>
            </div>
            <div class="flex_row_center mt5">
                <input @change="onFileChanged" :accept="fileType" type="file" ref="fileInput" style="display: none;" />
                <el-button type="primary" @click="onClickFile">选择固件</el-button>
                <el-button type="primary" @click="onClickCreate">创建</el-button>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import type { TbFirm } from '@/service/firm';
import firm from '@/service/firm';
import remote from '@/service/remote';
import { runAction } from '@/utils/ui';
import { formatDate, formatSize } from '@/utils/utils';
import { reactive, ref } from 'vue';


const FIRM_TYPS = ["上位机", "下位机"];

interface Form {
    firmType: number,
    version: string,
    description: string,
    fileName: string,
}

const fileInput = ref<HTMLInputElement | null>(null);
const fileType = ref('.apk');
let selectFile: File | null = null;
const firms = ref<TbFirm[]>([]);

const form = reactive<Form>({
    firmType: 0,
    version: '',
    description: '',
    fileName: '',
});

function onClickFile() {
    const finput = fileInput.value;
    if (finput == null) {
        return;
    }
    finput.click();
}

function onFileChanged(event: Event) {
    const input = event.target as HTMLInputElement;
    const files = input.files;
    if ((files == null) || (files.length == 0)) {
        return;
    }
    const file = files.item(0);
    if (file == null) {
        return;
    }
    selectFile = file;
    input.files = null;
    input.value = '';
    form.fileName = file.name;
}

async function onClickCreate() {
    await runAction('固件', '创建', async (dialog) => {
        if (selectFile == null) {
            throw '请选择固件文件';
        }
        const firm_type = form.firmType;
        const version = form.version;
        const description = form.description;
        if (version.length == 0) {
            throw '请输入版本号';
        }
        if (description.length == 0) {
            throw '请输入版本描述信息';
        }
        const name = selectFile.name;
        const body = new Uint8Array(await selectFile.arrayBuffer());
        await firm.create({
            firm_type,
            version,
            description,
            name,
            body
        }, (prog) => {
            dialog.setMsg(`进度:${prog}%`);
        });
        dialog.setMsg('更新固件');
        await update();
    });
}

async function update() {
    switch (form.firmType) {
        case 0: fileType.value = ".apk"; break;
        case 1: fileType.value = ".bin"; break;
    }
    selectFile = null;
    form.fileName = '';
    firms.value = await firm.query(form.firmType);
}

async function onClickDelete(id: number) {
    runAction('固件', '删除', async () => {
        await firm.delete(id);
        await update();
    });
}

async function onClickUpload(firm: TbFirm) {
    runAction('固件', '更新', async () => {
        switch (form.firmType) {
            case 0: {
                if (firm.size < (1 * 1024 * 1024)) {
                    throw '固件错误';
                }
                await remote.updateApp(firm.id);
            }; break;

            case 1: {
                if (firm.size > (1024 * 1024)) {
                    throw '固件错误';
                }
                await remote.updateMcu(firm.id);
            }; break;
        }
    });

}

update();

</script>

<style scoped>
.flb {
    width: 80px;
}

.finput {
    min-width: 120px;
    width: 30vw;
    max-width: 400px;
}

.fitem {
    max-width: 300px;
}
</style>
